/******************************************************************************
//             INTEL CORPORATION PROPRIETARY INFORMATION
//  This software is supplied under the terms of a license agreement or
//  nondisclosure agreement with Intel Corporation and may not be copied
//  or disclosed except in accordance with the terms of that agreement.
//    Copyright(c) 2001 Intel Corporation. All Rights Reserved.
//
//  VSS: 
//     $Workfile: $
//     $Revision: $
//     $Date:     $
//     $Archive:  $
//
//  Description:
//
//  History:
//     Date        Author        Changes
//     2001/8/7   Jerry Hu       Created  (Version 0.1)
//
********************************************************************************/

#include <stdio.h>
#include <stdlib.h>

#include <string.h>
#include <memory.h>

#include "ijx.h"
#include "_ijx.h"

#include "dib.h"
#include "jpgcmd.h"

#include <sys/time.h>

#define _GET_TIME_ON__ 1

struct timeval tv1,tv2, tv3, tv4;
struct timezone tz;

/*---------------------------------------------------------------------------*/

#define VERSION     "1.0 Beta"
#define DATE        "Nov.1, 2001"

#define BMPFILE     1
#define JPGFILE     2

#define BMP2JPG     1
#define JPG2BMP     2

/*---------------------------------------------------------------------------*/

typedef struct _CMDPARAMETERS
{   
    int nQuality;
    int nInterleave;
    int nJPEGMode;
    int nSubsampling;
    int nDesiredColor;
    int nConvertMode;
} CMDPARAMETERS;

///////////////////////////////////////////////////////////////////////////////
//  ShowBanner()
void ShowBanner()
{
#if 0
    printf("             INTEL CORPORATION PROPRIETARY INFORMATION\n");
    printf("  This software is supplied under the terms of a license agreement or\n");
    printf("  nondisclosure agreement with Intel Corporation and may not be copied\n");
    printf("  or disclosed except in accordance with the terms of that agreement.\n");
    printf("  Copyright (c) 2001 Intel China Software Lab. All Rights Reserved.\n\n");
    printf("JPEG <> DIB Conversion Tool, version %s. \n\n", VERSION);
#endif
}

///////////////////////////////////////////////////////////////////////////////
//  ShowCommand()
void ShowCommand()
{
#if 0
    printf ("jpegcmd.exe srcfile dstfile [-q=50] [-i=0] [-m=1] [-s=411] [-d=0]\n");
    printf ("q: (Compression)   Quality       [0, 100]\n");
    printf ("i: (Compression)   interleave \n");
    printf ("m: (Compression)   JPEG Mode     (1: Baseline, 2: Progressive) \n");
    printf ("s: (Compression)   Subsampling   (444, 411, 422) for RGB, RGB555, RGB565\n");
    printf ("d: (Decompression) Dedired Color (0: RGB, 1: ARGB, 2: RGB555, 3: RGB565)\n");
    printf ("                                  for 3 color channel image\n");
#endif
}

///////////////////////////////////////////////////////////////////////////////
//  ShowImageAttr()
void ShowImageAttr(MDIBSPEC *pDIBSpec)
{
#if 0
    printf ("Source Image Attributes:\n\n");
    printf ("Image Width:   %d\n", pDIBSpec->nWidth);
    printf ("Image Height:  %d\n", pDIBSpec->nHeight);
#endif
    switch (pDIBSpec->nClrMode) {
        case IIP_CM_GRAY:
            printf ("Image Type:    %s\n", "Gray");
            break;
        case IIP_CM_BGR:
            printf ("Image Type:    %s\n", "RGB");
            break;
        case IIP_CM_BGRA:
            printf ("Image Type:    %s\n", "ARGB");
            break;
        case IIP_CM_BGR555:
            printf ("Image Type:    %s\n", "RGB555");
            break;
        case IIP_CM_BGR565:
            printf ("Image Type:    %s\n", "RGB565");
            break;
        default:
            printf ("Image Type:    %s\n", "unknown");
            break;
    }
    printf ("Image Size:    %d\n", pDIBSpec->nDataSize);
}

///////////////////////////////////////////////////////////////////////////////
//  GetParamValue
void GetParamValue(int nType, char *pString, CMDPARAMETERS  *pParameters)
{
    int data;

    sscanf(pString, "%d", &data);

    switch (nType) {
        case 'q':
            pParameters->nQuality = data;
            if (0>=data||data>100) {
                pParameters->nQuality = 50;
                printf ("-q error, using defualt value (50).\n");
            }
            break;
        case 'i':
            pParameters->nInterleave = data;
            if (0>data) {
                pParameters->nInterleave = 0;
                printf ("-i error, using defualt value (0).\n");
            }
            break;
        case 'm':
            pParameters->nJPEGMode = data;
            switch (data) {
                case 0:
                    pParameters->nJPEGMode=IJX_MODE_BASELINE;
                    break;
                case 1:
                    pParameters->nJPEGMode=IJX_MODE_PROGRESSIVE;
                    break;
                default:
                    pParameters->nJPEGMode=IJX_MODE_BASELINE;
                    printf ("-m error, using defualt value (0).\n");
                    break;
            }
            break;
        case 's':
            pParameters->nSubsampling = data;
            switch (data) {
                case 444:
                    pParameters->nSubsampling = IIP_SM_NONE;
                    break;
                case 411:
                    pParameters->nSubsampling = IIP_SM_411;
                    break;
                case 422:
                    pParameters->nSubsampling = IIP_SM_422;
                    break;
                default:
                    pParameters->nSubsampling = IIP_SM_411;
                    printf ("-s error, using defualt value (411).\n");
                    break;
            }
            break;
        case 'd':
            pParameters->nDesiredColor = data;
            switch (data) {
                case 0:
                    pParameters->nDesiredColor = IIP_CM_GRAY|IIP_CM_BGR;
                    break;
                case 1:
                    pParameters->nDesiredColor = IIP_CM_GRAY|IIP_CM_BGRA;
                    break;
                case 2:
                    pParameters->nDesiredColor = IIP_CM_GRAY|IIP_CM_BGR555;
                    break;
                case 3:
                    pParameters->nDesiredColor = IIP_CM_GRAY|IIP_CM_BGR565;
                    break;
                default:
                    pParameters->nDesiredColor = IIP_CM_GRAY|IIP_CM_BGR;
                    printf ("-d error, using defualt value (0).\n");
                    break;
            }
            break;
    }
}

///////////////////////////////////////////////////////////////////////////////
//  Parse comand 
int ParseCmd(int argc, char* argv[], CMDPARAMETERS *pParameters)
{
    int i;
    int nSrcLen,  nDstLen;
    int nSrcType, nDstType;
    
    nSrcLen=strlen(argv[0]);
    if (0>=nSrcLen) {
        return FALSE;
    }

    nDstLen=strlen(argv[1]);
    if (0>=nDstLen) {
        return FALSE;
    }

    nSrcType=-1;
    nDstType=-1;

    pParameters->nConvertMode  = -1;

    /* Get source file type */
    if ( (argv[0][nSrcLen-1]=='b') ||
         (argv[0][nSrcLen-1]=='B') ||
         (argv[0][nSrcLen-2]=='m') ||
         (argv[0][nSrcLen-2]=='M') ||
         (argv[0][nSrcLen-3]=='p') ||
         (argv[0][nSrcLen-3]=='P') ) {
        nSrcType=BMPFILE;
    } else  if ( (argv[0][nSrcLen-1]=='j') ||
         (argv[0][nSrcLen-1]=='J') ||
         (argv[0][nSrcLen-2]=='p') ||
         (argv[0][nSrcLen-2]=='P') ||
         (argv[0][nSrcLen-3]=='g') ||
         (argv[0][nSrcLen-3]=='G') ) {
        nSrcType=JPGFILE;
    }

    /* Get destination file type */
    if ( (argv[1][nDstLen-1]=='b') ||
         (argv[1][nDstLen-1]=='B') ||
         (argv[1][nDstLen-2]=='m') ||
         (argv[1][nDstLen-2]=='M') ||
         (argv[1][nDstLen-3]=='p') ||
         (argv[1][nDstLen-3]=='P') ) {
        nDstType=BMPFILE;
    } else  if ( (argv[1][nDstLen-1]=='j') ||
         (argv[1][nDstLen-1]=='J') ||
         (argv[1][nDstLen-2]=='p') ||
         (argv[1][nDstLen-2]=='P') ||
         (argv[1][nDstLen-3]=='g') ||
         (argv[1][nDstLen-3]=='G') ) {
        nDstType=JPGFILE;
    }

    if ((BMPFILE==nSrcType)&&(JPGFILE==nDstType)) {
        pParameters->nConvertMode=BMP2JPG;
    } else if ((JPGFILE==nSrcType)&&(BMPFILE==nDstType)) {
        pParameters->nConvertMode=JPG2BMP;
    } else {
        return FALSE;
    }

    for (i=2; i<argc; i++) {
    
        if ( ('-'==argv[i][0])&&('='==argv[i][2]) ) {
            switch (argv[i][1]) {
                case 'q':
                case 'Q':
                    GetParamValue('q', &argv[i][3], pParameters);
                    break;
                case 'i':
                case 'I':
                    GetParamValue('i', &argv[i][3], pParameters);
                    break;
                case 'm':
                case 'M':
                    GetParamValue('m', &argv[i][3], pParameters);
                    break;
                case 's':
                case 'S':
                    GetParamValue('s', &argv[i][3], pParameters);
                    break;
                case 'd':
                case 'D':
                    GetParamValue('d', &argv[i][3], pParameters);
                    break;
            }
        }
    }

    return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
//  main
int main(int argc, char* argv[])
{
    FILE           *srcFile; 
    FILE           *dstFile;
    int            nSrcFileLen;
    int            nDstFileLen;
    MDIBSPEC       dibSpec;
    CMDPARAMETERS  parameters;

    ShowBanner();
    ShowCommand();

    if (3>argc) {
        printf("Command Error!\n");
        return FALSE;
    }

    memset(&dibSpec, 0, sizeof(MDIBSPEC));
    memset(&tv_vld, 0, sizeof(tv_vld));
    memset(&tv_iqit, 0, sizeof(tv_iqit));
    memset(&tv_cc, 0, sizeof(tv_cc));
    
    parameters.nQuality      = 50;
    parameters.nInterleave   = 0;
    parameters.nJPEGMode     = IJX_MODE_BASELINE;
    parameters.nSubsampling  = IIP_SM_411;
    parameters.nDesiredColor = IIP_CM_GRAY|IIP_CM_BGRA;
    parameters.nConvertMode  = -1;

    if (TRUE!=ParseCmd(argc-1, &argv[1], &parameters)) {
        printf("Command Error!\n");
        return FALSE;
    }

    printf ("\n");
    //printf ("Start Converting...\n\n");
    printf ("Source File:      %s \n", argv[1]);
    printf ("Destination File: %s \n", argv[2]);
    printf ("\n");


    srcFile=fopen(argv[1], "rb");
    dstFile=fopen(argv[2], "wb");
    if( NULL==srcFile ){
        printf ("Source file cannot be read! \n");
        return FALSE;
    }
    if( NULL==dstFile ){
        printf ("Destination file cannot be created! \n");
        fclose(srcFile);
        return FALSE;

    }

#ifdef _GET_TIME_ON__
   //
   // Get the first time for performance calculation
   //
   gettimeofday(&tv1,&tz);
#endif

    if (BMP2JPG==parameters.nConvertMode) {
        if (TRUE!=ReadDIBFile(&dibSpec, srcFile)) {
            printf("Source file read error.\n");
            fclose(srcFile);
            fclose(dstFile);
            DestoryDIB(&dibSpec);
            return FALSE;
        }
        ShowImageAttr(&dibSpec);
        if (TRUE!=BMPtoJPEG(parameters.nQuality, 
                            parameters.nInterleave,
                            parameters.nJPEGMode,
                            parameters.nSubsampling,
                            &dibSpec, 
                            dstFile)){
            printf("Destination file write error.\n");
            fclose(srcFile);
            fclose(dstFile);
            DestoryDIB(&dibSpec);
            return FALSE;
        }

        nSrcFileLen=ftell(srcFile);
        nDstFileLen=ftell(dstFile);

#if 0
        printf("\n");
        printf("Source file length:       %d\n", nSrcFileLen);
        printf("Destination file length:  %d\n", nDstFileLen);

        printf ("\nBMP -> JPEG Ok.\n");
#endif
        
    } else if (JPG2BMP==parameters.nConvertMode) {

        if (TRUE!=JPEGtoBMP ( parameters.nDesiredColor, &dibSpec, srcFile)) {
            printf("Source file read error.\n");
            fclose(srcFile);
            fclose(dstFile);
            DestoryDIB(&dibSpec);
            return FALSE;
        }

#ifdef _GET_TIME_ON__
   //
   // Get the first time for performance calculation
   //
   gettimeofday(&tv4,&tz);
#endif


        ShowImageAttr(&dibSpec);
        if (TRUE!=WriteDIBFile(&dibSpec, dstFile)) {
            printf("Destination file write error.\n");
        }

        nSrcFileLen=ftell(srcFile);
        nDstFileLen=ftell(dstFile);

#if 0
        printf("\n");
        printf("Source file length:       %d\n", nSrcFileLen);
        printf("Destination file length:  %d\n", nDstFileLen);

        printf ("\nJPG -> BMP Ok.\n");
#endif
        
    } else {
        printf("Command Error!\n");
        fclose(srcFile);
        fclose(dstFile);
        DestoryDIB(&dibSpec);
        return FALSE;
    }


#ifdef _GET_TIME_ON__
   //
   // Get the first time for performance calculation
   //
   gettimeofday(&tv2,&tz);
	
#if 0
	printf("========Start:\ntv1.sec: %ld\t\t", tv1.tv_sec);
	printf("tv1.usec: %ld\n", tv1.tv_usec);

	printf("=========Finish file Read: \ntv3.sec: %ld\t\t", tv3.tv_sec);
	printf("tv3.usec: %ld\n", tv3.tv_usec);
	printf("=========Finish decoding: \ntv4.sec: %ld\t\t", tv4.tv_sec);
	printf("tv4.usec: %ld\n", tv4.tv_usec);

	printf("=========End: \ntv2.sec: %ld\t\t", tv2.tv_sec);
	printf("tv2.usec: %ld\n\n", tv2.tv_usec);

	printf("JPEG File reading time: %ld (us)\n", ((tv3.tv_sec-tv1.tv_sec)*1000000+(tv3.tv_usec-tv1.tv_usec)));
#endif
	printf("VLD time : %ld (us)\n", (tv_vld.tv_sec*1000000+tv_vld.tv_usec));
	printf("IQIT time : %ld (us)\n", (tv_iqit.tv_sec*1000000+tv_iqit.tv_usec));
	printf("Color Conversion time : %ld (us)\n", (tv_cc.tv_sec*1000000+tv_cc.tv_usec));
	printf("JPEG Decoding & Color Convertion time : %ld (us)\n", ((tv4.tv_sec-tv3.tv_sec)*1000000+(tv4.tv_usec-tv3.tv_usec)));
	printf(" BMP File writing time: %ld (us)\n", ((tv2.tv_sec-tv4.tv_sec)*1000000+(tv2.tv_usec-tv4.tv_usec)));


#endif

    fclose(srcFile);
    fclose(dstFile);

    printf ("\n");
    DestoryDIB(&dibSpec);
    
	return 0;

}

/* EOF */
